import BaseActionCableConnector from '../yichat.web.share/helpers/BaseActionCableConnector'
import { playNewMessageNotificationInWidget } from './WidgetAudioNotificationHelper'
import { ON_AGENT_MESSAGE_RECEIVED } from '../constants/widgetBusEvents'
import { IFrameHelper } from './utils'

const isMessageInActiveConversation = (getters, message) => {
  const { conversationId: conversationId } = message
  const activeConversationId =
    getters['conversationAttributes/getConversationParams'].id
  return activeConversationId && conversationId !== activeConversationId
}

class ActionCableConnector extends BaseActionCableConnector {
  constructor(app, authToken, websocketURL) {
    super(app, authToken, websocketURL)
    this.events = {
      'message.created': this.onMessageCreated,
      'message.updated': this.onMessageUpdated,
      'conversation.typing_on': this.onTypingOn,
      'conversation.typing_off': this.onTypingOff,
      'conversation.status_changed': this.onStatusChange,
      'conversation.created': this.onConversationCreated,
      'presence.update': this.onPresenceUpdate,
      'contact.merged': this.onContactMerge
    }
  }

  onStatusChange = data => {
    if (data.status === 'resolved') {
      this.app.$store.dispatch('campaign/resetCampaign')
    }
    this.app.$store.dispatch('conversationAttributes/update', data)
  }

  onMessageCreated = data => {
    if (isMessageInActiveConversation(this.app.$store.getters, data)) {
      return
    }

    this.app.$store
      .dispatch('conversation/addOrUpdateMessage', data)
      .then(() => window.bus.$emit(ON_AGENT_MESSAGE_RECEIVED))

    IFrameHelper.sendMessage({ event: 'onMessage', data })
    if (data.sender_type === 'User') {
      playNewMessageNotificationInWidget()
    }
  }

  onMessageUpdated = data => {
    if (isMessageInActiveConversation(this.app.$store.getters, data)) {
      return
    }
    this.app.$store.dispatch('conversation/addOrUpdateMessage', data)
  }

  onConversationCreated = () => {
    this.app.$store.dispatch('conversationAttributes/getAttributes')
  }

  onPresenceUpdate = data => {
    this.app.$store.dispatch('agent/updatePresence', data.users)
  }

  onContactMerge = data => {
    const { pubsub_token: pubsubToken } = data
    ActionCableConnector.refreshConnector(pubsubToken)
  }

  onTypingOn = data => {
    const activeConversationId = this.app.$store.getters[
      'conversationAttributes/getConversationParams'
    ].id
    const isUserTypingOnAnotherConversation =
      data.conversation && data.conversation.id !== activeConversationId

    if (isUserTypingOnAnotherConversation || data.isPrivate) {
      return
    }
    this.clearTimer()
    this.app.$store.dispatch('conversation/toggleAgentTyping', {
      status: 'on'
    })
    this.initTimer()
  }

  onTypingOff = () => {
    this.clearTimer()
    this.app.$store.dispatch('conversation/toggleAgentTyping', {
      status: 'off'
    })
  }

  clearTimer = () => {
    if (this.CancelTyping) {
      clearTimeout(this.CancelTyping)
      this.CancelTyping = null
    }
  }

  initTimer = () => {
    // Turn off typing automatically after 30 seconds
    this.CancelTyping = setTimeout(() => {
      this.onTypingOff()
    }, 30000)
  }
}

export default ActionCableConnector
